#include "store.h"
#include "memory.h"

unsigned char ltv_code_buff[LTV_CODE_BUFF_SIZE] = {0};

char file_path[512] = "D:\\Project\\Clang\\NetShelf\\lib\\store\\";
int file_path_length = 0;

/**********************************************************************
     储存区域的划分
     1.检索与管理区分为模板、模板参数、字形码、标签设置显示内容
        检索与管理区分为模板、模板参数、字形码、标签设置显示内容
        建议长度：1K
        T 检索 STORE_INDEX
        V
            xxxx
     2.设备ID名称注册号
        设备ID名称注册号与显示：LTV模式
        建议长度：1K-8K
        L
        T 设备ID名称注册号 STORE_SHELF_AND_CARGO
        V
            货架号 货架MAC
            标签1	标签1唯一识别码    关联模板
            标签2	标签1唯一识别码    关联模板
            ...
     3.模板 模板参数
        L:16*1K*2
        T:模板和模板参数 STORE_TEMPLATE_CONTEXT
        V:
            1K模板1：L T：模板ID 数据
            1K模板参数1：L T:模板ID 数据

            1K模板2：L T：模板ID 数据
            1K模板参数2：L T:模板ID 数据
            ....
     4.字形码
        建议长度：1M
        L：总长度
        T 字形码 STORE_FONT_CODE
        V：LTV模式
            Font1: L：数据长度 T:字编码 V: fontSize:1Byte 字形码
            Font2: L：数据长度 T:字编码 V: fontSize:1Byte 字形码
            ....
 **********************************************************************/
STORE_TYPE store_type[] = {
        {STORE_INDEX,            "STORE_INDEX"},
        {STORE_SHELF_AND_CARGO,  "STORE_SHELF_AND_CARGO"},
        {STORE_TEMPLATE_CONTEXT, "STORE_TEMPLATE_CONTEXT"},
        {STORE_FONT_CODE,        "STORE_FONT_CODE"}
};


void store_init() {
    //头一次初始化的时候需要设置默认参数等
    int i = 0;
    unsigned char data[] = {
            //Shelf  sn id
            0xf0, 0x0f, 0xf0, 0x1f,
            //货物1 L T V:SN ID
            0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0xf0, 0x01,
            //货物2 L T V:SN ID
            0x00, 0x08, 0x00, 0x01, 0x00, 0x02, 0xf0, 0x02,
            //货物3 L T V:SN ID
            0x00, 0x08, 0x00, 0x01, 0x00, 0x03, 0xf0, 0x03,

    };
    LTV ltv = {
            0x0029,
            0xf0ff,
            data
    };
    for (; i < 4; i++) {
        store_param(ltv, store_type[i].type);
    }
}

void store_show() {
    int i = 0;
    LTV ltv;
    for (; i < 4; i++) {
        ltv = load_param(store_type[i].type);
        show_ltv(ltv);
    }
}

//内部函数 依据类型找到存储的数据
char *get_param_name(int type) {
    int i = 0;
    file_path_length = file_path_length > 0 ? file_path_length : string_length(file_path);

    //组合路径和文件名
    for (; i < 4; i++) {
        if (store_type[i].type == type) {
            string_replace(file_path, store_type[i].type_name, file_path_length);
            string_combine(".ltv", file_path);
            break;
        }
    }

    printf("file_path:%s\r\n", file_path);
    return file_path;
}


int store_param(LTV ltv, int type) {
    int i;
    FILE *pf = fopen(get_param_name(type), "w");
    unsigned char *p = ltv.value;

    if (pf == NULL) {
        return 1;
    } else {
        //添加头
        fputc(((ltv.length & 0xff00) >> 8), pf);
        fputc((ltv.length & 0x00ff), pf);

        fputc(((ltv.type & 0xff00) >> 8), pf);
        fputc((ltv.type & 0x00ff), pf);
        for (i = 0; i < ltv.length - 2; i++) {
            fputc(*p, pf);
            p++;
        }
    }
    fclose(pf);
    return 0;
}

LTV load_param(int type) {
    //读取策略 先加载长度然后根据长度读取
    LTV ltv;
    FILE *pf = fopen(get_param_name(type), "r");
    if (pf == NULL) {
        printf("fopen error\r\n");
    } else {
        //添加头
        fgets(ltv_code_buff, LTV_CODE_BUFF_SIZE, pf);
        ltv = ltv_decode(ltv_code_buff);
    }
    fclose(pf);
    return ltv;
}


STORE_INDEX_STRUCT *get_store_index_struct() {
    STORE_INDEX_STRUCT *store_index_struct = (STORE_INDEX_STRUCT *) memory_alloc(sizeof(STORE_INDEX_STRUCT));

    LTV ltv = load_param(STORE_INDEX);
    return store_index_struct;
}

int set_store_index_struct(STORE_INDEX_STRUCT *store_index_struct) {

    return 0;
}

STORE_SHELF_STRUCT *get_store_shelf_and_cargo_struct() {
//    typedef struct {
//        int cargo_sn;
//        int cargo_id;
//        struct STORE_SHELF_CARGO_STRUCT *next;
//    } STORE_SHELF_CARGO_STRUCT;
    STORE_SHELF_STRUCT *store_shelf_struct = (STORE_SHELF_STRUCT *) memory_alloc(sizeof(STORE_SHELF_STRUCT));
    STORE_SHELF_CARGO_STRUCT *store_shelf_cargo = NULL, *store_shelf_cargo_temp = NULL;
    int ltv_length = 0;
    unsigned char *cargo_data_start;

    (*store_shelf_struct).cargo = NULL;
    //加载储存的数据
    LTV ltv = load_param(STORE_SHELF_AND_CARGO);

    (*store_shelf_struct).shelf_sn = *(ltv.value) << 8 | *(ltv.value + 1);
    (*store_shelf_struct).shelf_id = *(ltv.value + 2) << 8 | *(ltv.value + 3);
    //处理偏移量
    cargo_data_start = ltv.value;
    cargo_data_start += 4;

    ltv_length = ltv.length - 8;

    //解析货物的序列
    for (; ltv_length > 0; ltv_length -= ltv.length) {
        ltv = ltv_decode(cargo_data_start);

        store_shelf_cargo = (STORE_SHELF_CARGO_STRUCT *) memory_alloc(sizeof(STORE_SHELF_CARGO_STRUCT));
        //填充数据
        (*store_shelf_cargo).cargo_id = *(ltv.value) << 8 | *(ltv.value + 1);
        (*store_shelf_cargo).cargo_sn = *(ltv.value + 2) << 8 | *(ltv.value + 3);
        (*store_shelf_cargo).next = NULL;
        if ((*store_shelf_struct).cargo != NULL) {
            store_shelf_cargo_temp = (*store_shelf_struct).cargo;
            (*store_shelf_struct).cargo = store_shelf_cargo;
            (*store_shelf_cargo).next = (struct STORE_SHELF_CARGO_STRUCT *) store_shelf_cargo_temp;
        } else {
            (*store_shelf_struct).cargo = store_shelf_cargo;
        }
        cargo_data_start += ltv.length;
    }
    return store_shelf_struct;
}


int set_store_shelf_and_cargo_struct(STORE_SHELF_STRUCT *store_shelf_struct) {

    return 0;
}

STORE_TEMPLATE_CONTEXT_STRUCT *get_store_template_context_struct() {

    unsigned char *base_address = (unsigned char *) 0xff000000;
    int i;

    STORE_TEMPLATE_CONTEXT_STRUCT *store_template_context_struct = (STORE_TEMPLATE_CONTEXT_STRUCT *) memory_alloc(
            sizeof(STORE_TEMPLATE_CONTEXT_STRUCT));
    STORE_TEMPLATE_CONTEXT_STRUCT *curr = store_template_context_struct;
    STORE_TEMPLATE_CONTEXT_STRUCT *next = NULL;

    //ToDo 需要根据地址获取到储存的内容
    (*store_template_context_struct).template_id = 0;
    (*store_template_context_struct).template = (unsigned char *) base_address;
    (*store_template_context_struct).template_context = (unsigned char *) (base_address + 1024);
    //依据定义直接根据基地址算出偏移量 并加载出数据
    for (i = 0; i < MAX_STORE_TEMPLATE_SIZE - 1; i += 2) {
        next = (STORE_TEMPLATE_CONTEXT_STRUCT *) memory_alloc(sizeof(STORE_TEMPLATE_CONTEXT_STRUCT));

        //ToDo 需要根据地址获取到储存的内容
        (*next).template_id = 0;
        (*next).template = (unsigned char *) (base_address + 1024 * (i + 1));
        (*next).template_context = (unsigned char *) (base_address + 1024 * (i + 2));
        (*curr).next = (struct STORE_TEMPLATE_CONTEXT_STRUCT *) next;
        curr = next;

    }

//    LTV ltv = load_param(STORE_TEMPLATE_CONTEXT);

    return store_template_context_struct;
}


int set_store_template_context_struct(STORE_TEMPLATE_CONTEXT_STRUCT *store_template_context_struct) {

    return 0;
}

STORE_FONT_CODE_STRUCT *get_store_font_code_struct() {
    STORE_FONT_CODE_STRUCT *store_font_code_struct = (STORE_FONT_CODE_STRUCT *) memory_alloc(
            sizeof(STORE_FONT_CODE_STRUCT));

    STORE_FONT_CODE_STRUCT *curr = store_font_code_struct;
    STORE_FONT_CODE_STRUCT *next = NULL;
    int ltv_length = 0;
    unsigned char *font_data_start = NULL;


    //加载储存的数据
    LTV ltv = load_param(STORE_FONT_CODE);
    ltv_length = ltv.length;
    font_data_start = ltv.value;

    //Font1: L：数据长度 T:字编码 V: fontSize:1Byte 字形码
    ltv = ltv_decode(font_data_start);
    (*store_font_code_struct).font_code = ltv.type;
    (*store_font_code_struct).length = ltv.length;
    (*store_font_code_struct).font_size = *(ltv.value);
    (*store_font_code_struct).font = (ltv.value + 1);//ToDo 此处可能存在问题
    (*store_font_code_struct).next = NULL;

    //跳过第一个
    font_data_start += ltv.length;
    ltv_length = ltv_length - 4 - ltv.length;

    //解析货物的序列
    for (; ltv_length > 0; ltv_length -= ltv.length) {
        ltv = ltv_decode(font_data_start);

        next = (STORE_FONT_CODE_STRUCT *) memory_alloc(sizeof(STORE_FONT_CODE_STRUCT));
        //填充数据
        (*next).font_code = ltv.type;
        (*next).length = ltv.length;
        (*next).font_size = *(ltv.value);
        (*next).font = (ltv.value + 1);//ToDo 此处可能存在问题
        (*next).next = NULL;

        (*curr).next = (struct STORE_FONT_CODE_STRUCT *) next;
        curr = next;
        font_data_start += ltv.length;
    }

    return store_font_code_struct;
}

int set_store_font_code_struct(STORE_FONT_CODE_STRUCT *store_font_code_struct) {
    return 0;
}